#ifndef __P_MACHINE_HH__
#include "data_structures.hh"
#include <string>

enum pcode_opcodes {
  pcode_nop,
  pcode_add,
  pcode_and,
  pcode_or,
  pcode_cmp_eq,
  pcode_cmp_lt,
  pcode_cmp_gt,
  pcode_exchange,
  pcode_sub,
  pcode_dup,
  pcode_dupn,
  pcode_lnot,
  pcode_look_long = 0x80,
  pcode_look_short,
  pcode_write_mesg,
  pcode_nl,
  pcode_examine_obj,
  pcode_move_obj,
  pcode_swap_obj,
  pcode_print_objs,
  pcode_print_exits,
  pcode_print_tos,
  pcode_inventory,
  pcode_finish,
  pcode_load_false = 0x100,
  pcode_load_true,
  pcode_load_here,
  pcode_load_verb,
  pcode_load_adverb,
  pcode_load_obj1,
  pcode_load_adj1,
  pcode_load_obj2,
  pcode_load_adj2,
  pcode_load_counter,
  pcode_load_switch,
  pcode_load_visited,
  pcode_load_obj_pos,
  pcode_load_obj_weight,
  pcode_store_here = 0x202,
  pcode_store_verb,
  pcode_store_adverb,
  pcode_store_obj1,
  pcode_store_adj1,
  pcode_store_obj2,
  pcode_store_adj2,
  pcode_store_counter,
  pcode_store_switch,
  pcode_end_on_false = 0x300,
  pcode_end_on_true,
  pcode_load_immediate = 0x4100,
  pcode_millegal = 0x4a7c,
  pcode_illegal = 0xFFFF
};

/*! \brief run p-code
 *
 * Run p-code and change the current adventure object if necessary..
 *
 * \param adv adventure object
 * \param code the code to run
 * \param trace if true print a trace to stdout
 * \return 0 = false return of code (keep running), 1 = true return of code (finish current adventure loop), -1 = neither true or false (error?)
 */
int prun(Adventure &adv, const pcode_array &code, bool trace = false);


/*! \brief load pcode from string
 *
 * Load the pcode from a string, string is interpreted as space
 * separated hex values.
 *
 * \param s string
 * \return array of pcode opcodes
 */
pcode_array pcode_from_string(const std::string &s);


#endif
